package model

import (
	"github.com/tianjigames/fairy/constants"
	"github.com/tianjigames/fairy/pojo"
	"github.com/tianjigames/fairy/protos"
	"github.com/tianjigames/fairy/template"
	"github.com/topfreegames/pitaya"
	"strconv"
)

type (
	PlayerObject struct {
		BaseCharObj
		SessionId string
		PlayerGuid int
		PlayerData *pojo.PlayerData
		MMissionList *MissionDataList
		MaAttrBackup *PlayerAttrBackup
		DropItemList *DropItemList
		Bag *PlayerBag
		TreasureBag *PlayerTreasureBag
		RideList *RideList
		MFabao *Fabao
		WingList *WingList
		MAuctionList *PlayerAuctionList
		MTitleData *TitleData
		MWeddingData *WeddingData
		GangFightBetMap map[int64][]*BetData
		MBattleState int
		PStateTime *NowTimer
		RegTimer *NowTimer
		MDisconnectTimer *NowTimer
		TeamVoteTimer *NowTimer
		WaitConnectByOffline bool
		MBFirstLoginGame bool
		OnLineWin bool
		MPKMode int
		LastPKMode int
		NPlayerSceneStatus int
		NPlayerSportStatus int
		MGameState int
		MLogicStata *BitFlagSet
		RefPlayerAttrTimer *NowTimer
		BeginKickTimer *NowTimer
		SelfRanks *PlayerRank
		Robots map[int64]*protos.MsgRankData
		EnemyID int
		MatchId int
		IsMirror4Enemy bool
		EnemyData *protos.MsgRankData
		WuKuiMatchId int
		NUpdateFiveMinute int
		GangContribution int
		GangMaxContribution int
		GangName string
		GangJob int
		GangCamp int
		GangGiftCount int
		GangSkillList []int
		BWatingCreateGang bool
		GangWefareDayTime int64
		NextTickSecond int64
		NextTickMinute int64
		NextHourTime int64
		NextDayTime int64
		EnAllTimes int
		JoyoAllTimes int
		SucEn bool
		ChatTick []int64
		BChatInCD []bool
		VipData *PlayerVipData
		CombatPower int
		BCombatPowerModify bool
		BActivityCheck bool
		BChargeActivityCheck bool
		BServenDataActCheck bool
		GmAuthorityLevel int
		LastHp int
		LastMp int
		DieTime int
		PlayerPkHitBackList *PlayerPkHitBackList
		TeamInfo *protos.MsgTeamInfo
		PreInvitedPlayerGuid int64
		FollowIds []int
		FollowId int
		FollowTimer *NowTimer
		JdqxInvateType int
		TeanInfoJieYi *protos.MsgTeamInfo
		JieYiCacheName string
		JieYiAgree []int
		TeamInfoMarriage *protos.MsgTeamInfo
		MActivityData *ActivityData
		MChargetActivityData *ActivityData
		MSevenActData *ActivityData
		MTimecutData *ActivityData
		MFashionListData *FashionListData
		TickForMusicState int
		FriendIntimacyTime map[int64]int64
		FriendIntimacyIncForTeam map[int64]int
		BNewPlayerGuiding bool
		GangDonateCount int
		GangCircleTime int64
		GangCircleMissionId string
		GangTreePoint int
		GangTreePray int
		GangTreeTime int
		GangTreePouring bool
		GangBaseInfoList []*protos.MsgGangBaseInfo
		GatherList []GatherInfo
		LanMap map[int]*protos.MsgRankData
		TempLanMap map[int]*protos.MsgRankData
		PveLastAskTime int64
		LastWorldChatMsgStr string
		FlagId int
		NUpdatePerSeconds int
		QmlwBuffTick int
		MIngotShopData *IngotShopData
		GangTreeBubble []*TreeBubbleInfo
	}

	TreeBubbleInfo struct {
		BubbleType int
		BValid bool
		CreateTime int64
	}
)

/**
实例化一个游戏玩家对象
 */
func NewPlayerObject(playerData *pojo.PlayerData) *PlayerObject {
	bCharObj := NewBaseCharObj()
	bCharObj.MSkillData = UnSerializeSkillData(playerData.SkillData)
	rs := &PlayerObject{
		BaseCharObj:*bCharObj,
		PlayerData: playerData,
		MaAttrBackup: &PlayerAttrBackup{},
		DropItemList:NewDropItemList(),
		MBattleState: constants.PlayerBattleStatePatrol,
		PStateTime: NewNowTimer(),
		RegTimer: NewNowTimer(),
		MDisconnectTimer: NewNowTimer(),
		TeamVoteTimer: NewNowTimer(),
		WaitConnectByOffline: true,
		MPKMode: int(protos.PkModeType_Peace),
		LastPKMode: int(protos.PkModeType_Peace),
		MGameState: constants.PlayerStateInvalid,
		MLogicStata: NewBitFlagSet(int(MaxLock)),
		RefPlayerAttrTimer: NewNowTimer(),
		BeginKickTimer: NewNowTimer(),
		SelfRanks: NewPlayerRank(),
		EnemyID: -1,
		MatchId: -1,
		WuKuiMatchId: -1,
		ChatTick: make([]int64,constants.ChannelNum),
		BChatInCD: make([]bool,constants.ChannelNum),
		FollowIds: make([]int,0),
		FollowTimer: NewNowTimer(),
		JieYiAgree:make([]int,constants.JieYiPlayerMaxCount),
		GatherList: make([]GatherInfo,0),
		LanMap: map[int]*protos.MsgRankData{},
		TempLanMap: map[int]*protos.MsgRankData{},
		GangTreeBubble: make([]*TreeBubbleInfo,10),

		MMissionList:         UnSerializeMissionListData(playerData.MissionData),
		PlayerPkHitBackList:  NewPlayerHitBackList(),
		MTitleData:           UnSerializeTitleData(playerData.TitleData),
		WingList:             NewWingList(playerData.WingId,playerData.WingData),
		MIngotShopData:       UnSerializeIngotShopData(playerData.IngotShopData),
		MActivityData:        UnSerializeActivityData(playerData.ActivityData),
		MChargetActivityData: UnSerializeActivityData(playerData.ChargeActivityData),
		MSevenActData:        UnSerializeActivityData(playerData.SevenDayActData),
		MTimecutData:         UnSerializeActivityData(playerData.TimecutData),
		MWeddingData:         UnSerializeWeddingData(playerData.WeddingGuestGuids),
		GangFightBetMap:      UnSerializeBetData(playerData.BetFun),
		MFashionListData: 	  UnSerializeFashionListData(playerData.FashionData),

		GangDonateCount: -1,
	}

	rs.MSkillData.GangSkillRepairModel(playerData.Guid)
	if rs.GangFightBetMap == nil {
		rs.GangFightBetMap = map[int64][]*BetData{}
	}

	for i:=0;i<constants.ChannelNum;i++ {
		rs.ChatTick[i] = 0
		rs.BChatInCD[i] = false
	}

	for i:=0;i< len(rs.GangTreeBubble);i++ {
		rs.GangTreeBubble[i] = &TreeBubbleInfo{
			BValid: false,
		}
	}

	return rs
}

func (p *PlayerObject) GetLogoutTime() int64 {
	return p.PlayerData.LogoutTime
}

func (p *PlayerObject) GetId() int {
	return p.PlayerData.PlayerId
}

func (p *PlayerObject) GetGuid() int64 {
	return p.PlayerData.Guid
}

func (p *PlayerObject) GetChaoDuItemId() int {
	for _,item := range p.Bag.Items {
		if item == nil || !item.IsValid() {
			continue
		}

		if item.MItemCfg.Type == int(constants.ItemTypeMisssion) && item.MItemCfg.SubType == int(constants.MissionTypeChaoDu) {
			return item.GetId()
		}
	}

	return 0
}

/**
获取组队id
 */
func (p *PlayerObject) GetTeamId() int {
	if p.TeamInfo != nil {
		return int(p.TeamInfo.TeamId)
	}

	return 0
}

func (p *PlayerObject) GetRoleName() string {
	return p.PlayerData.RoleName
}

func (p *PlayerObject) GetLv() int {
	return p.PlayerData.Rolelevel
}

func (p *PlayerObject) GetCareerId() int {
	return p.PlayerData.CareerId
}

func (p *PlayerObject) GetSexId() int {
	return int(p.PlayerData.SexId)
}

/**
判断角色是否处于跟随状态
 */
func (p *PlayerObject) IsFollow() bool {
	return p.FollowId != 0 && p.FollowId != p.GetId()
}

/**
判断是否可以物理攻击
 */
func (p *PlayerObject) IsPhysicAttack() bool {
	lv := p.PlayerData.Rolelevel
	attrFactor := pitaya.GetTemplateById(template.AttrFactorKey,strconv.FormatInt(int64(p.GetCareerId()*1000 + lv),10))
	if attrFactor != nil {
		return attrFactor.(*template.AttrFactor).AttType == 1
	}

	return false
}

func (p *PlayerObject) GetSceneID() int {
	return p.PlayerData.SceneId
}

/**
获取玩家的移动速度
 */
func (p *PlayerObject) GetBaseSpeed() int {
	at := constants.AttrMoveSpeed
	return p.MAAttributeList.GetBaseAttr(&at)
}

/**
判断玩家是队长
 */
func (p *PlayerObject) IsTeamLeader() bool {
	return p.GetLeaderId() == p.GetId()
}

/**
获取组队队长id
 */
func (p *PlayerObject) GetLeaderId() int {
	if p.TeamInfo == nil {
		return 0
	}

	for _,member := range p.TeamInfo.TeamMemberList {
		if member.IsLeader == 1 {
			return int(member.PlayerId)
		}
	}

	return 0
}

/**
另外一个玩家是否可以看到自己
 */
func (p *PlayerObject) CanViewMe(other *PlayerObject) bool {
	if p.GetId() == other.GetId() && p.GetType() == other.GetType() {
		return false
	}

	if !other.IsActive() {
		return false
	}

	if other.MGameState != constants.PlayerStateNormal &&
		other.MGameState != constants.PlayerStateWaitEnterSceneOk &&
		other.MGameState != constants.PlayerStateWaitDisconnect{
		return false
	}

	if other.GetSceneID() != p.GetSceneID() {
		return false
	}

	if !p.IsVisible() {
		return false
	}

	if p.GetScene() == nil {
		return false
	}

	return true
}

/**
判断某个玩家是否可视
 */
func (p *PlayerObject) IsVisible() bool {
	return p.MGameState != constants.PlayerStateSportOut
}

/**
获取战队id
 */
func (p *PlayerObject) GetGangId() int64 {
	if p.PlayerData != nil {
		return p.PlayerData.GangId
	}

	return -1
}

/**
获取vip等级
 */
func (p *PlayerObject) GetVipLevel() int {
	if p.VipData != nil {
		return p.VipData.VipLevel
	}

	return -1
}

/**
获取法宝信息
 */
func (p *PlayerObject) GetFabaoInfoMsg() *protos.MsgFabaoInfo {
	if p.MFabao == nil {
		return nil
	}

	skillList := make([]int32,0)
	for _,v := range p.MFabao.SkillList {
		skillList = append(skillList,int32(v))
	}

	return &protos.MsgFabaoInfo{
		FabaoId: int32(p.MFabao.GetId()),
		ShowId: int32(p.MFabao.GetShowTemplateId()),
		CurExp: int32(p.MFabao.GetFabaoExp()),
		LuckyValue: int32(p.MFabao.GetFabaoLuck()),
		SkillList: skillList,
	}
}




